<?php defined('SYSPATH') or die('No direct script access.');

/**
 *Copyright www.stourweb.com
 *Author: nilsir
 *QQ: 2758691158
 *Time: 2017/7/18 9:55
 *Desc: PC端支付宝即时交易
 */
class Controller_Pc_Alipaycash extends Stourweb_Controller
{
    //支付id
    private $_id = 11;
    //支付宝即时交易目录
    private $_alipay_cash_dir = '';
    //异步通知
    private $_notify_url = '';
    //同步通知
    private $_return_url = '';
    //日志目录
    const LOGSDIR = 'alipaycash';

    public function before()
    {
        parent::before();
        $this->_alipay_cash_dir = ALIPAY . 'vendor' . DS . 'pc' . DS . 'alipay_cash' . DS;
        $this->_notify_url = $GLOBALS['cfg_basehost'] . '/alipaycash/pc/notify_url';
        $this->_return_url = $GLOBALS['cfg_basehost'] . '/alipaycash/pc/return_url';
    }

    public function action_index()
    {
        $ordersn = Common::remove_xss(Arr::get($_GET, 'ordersn'));
        $info = Model_Member_Order::info($ordersn);
        $info['typename'] = Model_Model::get_module_name($info['typeid']);
        self::_checked_ordersn($ordersn);
        $this->submit($info);
        exit;
    }

    /**
     * @function 检测订单状态
     * @param $ordersn
     * @return bool
     */
    private static function _checked_ordersn($ordersn)
    {
        $bool = false;
        $info['ordersn'] = $ordersn;
        if (! preg_match('~^\d+$~', $ordersn))
        {
            //订单号格式错误
            $info['sign'] = 25;
        }
        else if (Model_Member_Order::not_exists($ordersn))
        {
            //订单不存在
            $info['sign'] = 26;
        }
        else if (Model_Member_Order::payed($ordersn))
        {
            //订单已支付
            $info['sign'] = 24;
        }
        else
        {
            $bool = true;
        }
        //订单号错误提示
        if (! $bool)
        {
            St_Payment::pay_status($info);
            exit;
        }

        return $bool;
    }

    public function submit($data)
    {
        require_once($this->_alipay_cash_dir . "lib/alipay_submit.class.php");
        $aliPay = new AlipaySubmit();
        //https://open.alipay.com 账户中心->密钥管理->开放平台密钥，填写添加了电脑网站支付的应用的APPID
        $appid = Model_Sysconfig::get_configs(0, 'cfg_alipay_appid', true);
        //付款成功后的同步回调地址
        $returnUrl = $this->_return_url;
        //付款成功后的异步回调地址
        $notifyUrl = $this->_notify_url;
        //你自己的商品订单号，不能重复
        $outTradeNo = $data['ordersn'];
        //付款金额，单位:元
        $payAmount = $data['total'];
        //订单标题
        $orderName = $data['ordersn'];
        //商品名称
        $projectName = $data['productname'];
        //签名算法类型，支持RSA2和RSA，推荐使用RSA2
        $signType = 'RSA2';
        //商户私钥，填写对应签名算法类型的私钥，如何生成密钥参考：https://docs.open.alipay.com/291/105971和https://docs.open.alipay
        $rsaPrivateKey=Model_Sysconfig::get_configs(0, 'merchant_private_key', true);;
        $aliPay->setAppid($appid);
        $aliPay->setReturnUrl($returnUrl);
        $aliPay->setNotifyUrl($notifyUrl);
        $aliPay->setRsaPrivateKey($rsaPrivateKey);
        $aliPay->setTotalFee($payAmount);
        $aliPay->setOutTradeNo($outTradeNo);
        $aliPay->setOrderName($orderName);
        $aliPay->setProjectName(St_Functions::replaceSpecialChar($projectName));
        $aliPay->setSignType($signType);
        $sHtml = $aliPay->doPay();
        echo $sHtml;
    }


    /**
     * @function 服务器异步通知页面路径
     * @return string
     */
    public function action_notify_url()
    {
        header('Content-type:text/html; Charset=utf-8');
        include($this->_alipay_cash_dir . 'lib/alipay_notify.class.php');
        //支付宝公钥，账户中心->密钥管理->开放平台密钥，找到添加了支付功能的应用，根据你的加密类型，查看支付宝公钥
        $alipayPublicKey=Model_Sysconfig::get_configs(0, 'alipay_public_key', true);
        $aliPay = new AlipayNotify($alipayPublicKey);
        //验证签名
        $result = $aliPay->rsaCheck($_POST);
        if ($result===true) {
            if ($_POST['trade_status'] == 'TRADE_SUCCESS') {
                $tip = '信息:支付宝即时交易(异),订单金额与实际支付不一致';
                if (St_Payment::total_fee_confirm($_POST['out_trade_no'], $_POST['total_amount'], $tip)) {
                    $payset = Model_Payset::get_payset_info_by_id($this->_id);
                    //写入支付宝流水号
                    $online_transaction_no = array('source'=>'alipay','transaction_no'=>$_POST['trade_no']);
                    DB::update('member_order')->set(array('online_transaction_no'=>json_encode($online_transaction_no)))
                        ->where('ordersn','=',$_POST['out_trade_no'])
                        ->execute();
                    St_Payment::pay_success($_POST['out_trade_no'], $payset['name'] . '(电脑端)');
                }
            } else {
                new Pay_Exception("状态:{$_POST['trade_status']}", 0, self::LOGSDIR);
            }
            echo 'success';
            exit();
        }
        echo 'error';
        new Pay_Exception("信息:合法性验证失败");
        self::_write_log($this->request->action());
        exit();
    }

    /**
     * @function 页面跳转同步通知页面路径
     */
    public function action_return_url()
    {
        header('Content-type:text/html; Charset=utf-8');
        include($this->_alipay_cash_dir . 'lib/alipay_notify.class.php');
        //支付宝公钥，账户中心->密钥管理->开放平台密钥，找到添加了支付功能的应用，根据你的加密类型，查看支付宝公钥
        $alipayPublicKey=Model_Sysconfig::get_configs(0, 'alipay_public_key', true);
        $aliPay = new AlipayNotify($alipayPublicKey);
        //验证签名
        $result = $aliPay->rsaCheck($_GET);
        if ($result) {
            $info['sign'] = '11';
        } else {
            $info['sign'] = '22';
            new Pay_Exception("状态:支付宝即时交易(同)数据有效性验证失败");
        }
        $info['ordersn'] = $_GET['out_trade_no'];
        self::_write_log($this->request->action());
        St_Payment::pay_status($info);
    }

    /**
     * @function 将回调参数写入日志文件
     * @param $method
     */
    private static function _write_log($method)
    {
        $pay_class = __CLASS__;
        $base_path = rtrim(BASEPATH, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR .
            'data' . DIRECTORY_SEPARATOR .
            'logs' . DIRECTORY_SEPARATOR .
            'payment' . DIRECTORY_SEPARATOR;
        $pay_log_dir = $base_path . self::LOGSDIR . DIRECTORY_SEPARATOR . 'callback' . DIRECTORY_SEPARATOR;
        if (! file_exists($pay_log_dir))
        {
            mkdir($pay_log_dir, 0777, true);
        }
        //日志文件
        $file = $pay_log_dir . str_replace('pay_', '', strtolower($pay_class)) . '_' . date('ymd') . '.txt';
        $data = "\r\n[{$method}:" . date('YmdHis');
        foreach ($_REQUEST as $k => $v)
        {
            $data .= " {$k}={$v}";
        }
        $data .= ']';
        file_put_contents($file, $data, FILE_APPEND);
    }
}